import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './modules/user/user.module';
import { User } from './modules/user/entities/user.entity';
import { Role } from './modules/user/entities/role.entity';
import { Permission } from './modules/user/entities/permission.entity';
import { RedisModule } from './modules/redis/redis.module';
import { EmailModule } from './modules/email/email.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { LoginGuard } from './guards/login.guard';
import { APP_GUARD } from '@nestjs/core';
import { PermissionGuard } from './guards/permission.guard';
import { MeetingRoomModule } from './modules/meeting-room/meeting-room.module';
import { MeetingRoom } from './modules/meeting-room/entities/meeting-room.entity';
import { BookingModule } from './modules/booking/booking.module';
import { Booking } from './modules/booking/entities/booking.entity';
import { StatisticModule } from './modules/statistic/statistic.module';
import { MinioModule } from './modules/minio/minio.module';
import * as path from 'path';

const configMap = {
  dev: 'src/config.dev.env',
  prod: path.join(__dirname, 'config.prod.env'),
};

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get<string>('MYSQL_SERVER_HOST'),
        port: configService.get<number>('MYSQL_SERVER_PORT'),
        username: configService.get<string>('MYSQL_SERVER_USERNAME'),
        password: configService.get<string>('MYSQL_SERVER_PASSWORD'),
        database: configService.get<string>('MYSQL_SERVER_DATABASE'),
        synchronize: process.env.NODE_ENV === 'dev' ? true : false,
        logging: process.env.NODE_ENV === 'dev' ? true : false,
        entities: [User, Role, Permission, MeetingRoom, Booking],
        poolSize: 10,
        connectorPackage: 'mysql2',
        extra: {},
      }),
      inject: [ConfigService],
    }),
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: configMap[process.env.NODE_ENV as string],
    }),
    JwtModule.registerAsync({
      global: true,
      useFactory(configService: ConfigService) {
        return {
          secret: configService.get('JWT_SECRET'),
          signOptions: {
            expiresIn: configService.get('JWT_ACCESS_TOKEN_EXPIRES_TIME'),
          },
        };
      },
      inject: [ConfigService],
    }),
    UserModule,
    RedisModule,
    EmailModule,
    MeetingRoomModule,
    BookingModule,
    StatisticModule,
    MinioModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_GUARD,
      useClass: LoginGuard,
    },
    {
      provide: APP_GUARD,
      useClass: PermissionGuard,
    },
  ],
})
export class AppModule {}
